﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Globalization;

namespace Boomerang.Common.Tracing
{
    public class NumberedStream : System.IO.Stream
    {
        private FileStream FStream;
        private String FilePath;
        private String FileBase;
        private String FileExt;
        private long DataWritten;
        private long FileQuota;
        private int FileCount;

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public NumberedStream(string fileName)
        {
            //Handle all exceptions within this class, since tracing shouldn't crash a service
            try
            {
                FilePath = Path.GetDirectoryName(fileName);
                FileBase = Path.GetFileNameWithoutExtension(fileName);
                FileExt = Path.GetExtension(fileName);

                if (string.IsNullOrEmpty(FilePath))
                {
                    FilePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                }

                FStream = new FileStream( GetFileName(FilePath,FileBase,FileExt), FileMode.Create);
            }
            catch { }

        }

        private string GetFileName(string filePath,string fileBase,string fileExt)
        {
            string baseName = Path.Combine(filePath,fileBase+"-"+DateTime.Now.ToString("yyyyMMdd",CultureInfo.InvariantCulture));
            string name = string.Format(CultureInfo.InvariantCulture,"{0}_{1:000}{2}",baseName,FileCount,fileExt);
            while (File.Exists(name))
            {
                FileCount++;
                name = string.Format(CultureInfo.InvariantCulture,"{0}_{1:000}{2}",baseName,FileCount,fileExt);                               
            }
            return name;
        }

        public long MaxQuotaSize
        {
            get
            {
                return FileQuota;
            }
            set
            {
                FileQuota = value;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public void SwitchFiles()
        {
            try
            {
                //Close current file, open next file (deleting its contents)

                DataWritten = 0;
                FStream.Close();
                FStream = new FileStream(GetFileName(FilePath,FileBase,FileExt), FileMode.Create);
            }
            catch (Exception) { }
        }

        public bool IsOverQuota
        {
            get
            {
                return (DataWritten >= FileQuota);
            }

        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override bool CanRead
        {
            get
            {
                try
                {
                    return FStream.CanRead;
                }
                catch (Exception)
                {
                    return true;
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override bool CanSeek
        {
            get
            {
                try
                {
                    return FStream.CanSeek;
                }
                catch (Exception)
                {
                    return false;
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override long Length
        {
            get
            {
                try
                {
                    return FStream.Length;
                }
                catch (Exception)
                {
                    return -1;
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override long Position
        {
            get
            {
                try
                {
                    return FStream.Position;
                }
                catch (Exception)
                {
                    return -1;
                }
            }
            set
            {
                try
                {
                    FStream.Position = Position;
                }
                catch (Exception) { }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override bool CanWrite
        {
            get
            {
                try
                {
                    return FStream.CanWrite;
                }
                catch (Exception)
                {
                    return true;
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override void Flush()
        {
            try
            {
                FStream.Flush();
            }
            catch (Exception) { }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override long Seek(long offset, SeekOrigin origin)
        {
            try
            {
                return FStream.Seek(offset, origin);
            }
            catch (Exception)
            {
                return -1;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override void SetLength(long value)
        {
            try
            {
                FStream.SetLength(value);
            }
            catch (Exception) { }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override void Write(byte[] buffer, int offset, int count)
        {
            try
            {
                //Write to current file

                FStream.Write(buffer, offset, count);
                DataWritten += count;

            }
            catch (Exception) { }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override int Read(byte[] buffer, int offset, int count)
        {
            try
            {
                return FStream.Read(buffer, offset, count);
            }
            catch (Exception)
            {
                return -1;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public override void Close()
        {
            try
            {
                FStream.Close();
            }
            catch (Exception) { }
        }



    }
}
